import axios, { AxiosResponse } from 'axios'
import config from '@/config'


/**
 * @param {QueryParams} queryParams
 */
function buildQueryParams(queryParams) {
  const { query, withRels, relsQuery, sorts, all = false } = queryParams
  const { currentPage = 1, limit = config.api.limit } = (queryParams.pagination || {})
  return {
    query: query ? JSON.stringify(query) : undefined,
    withRels: withRels ? JSON.stringify(withRels) : undefined,
    relsQuery: relsQuery ? JSON.stringify(relsQuery) : undefined,
    sorts: sorts ? JSON.stringify(sorts) : undefined,
    page: currentPage,
    limit,
    all
  }
}

function idPath(path, id) {
  return `${path}/${id}`
}

/**
 * @param {{queryParams: QueryParams, data: any}} config
 * @returns {Promise<AxiosResponse>}
 */
async function request(method, path, config = {}) {
  const { queryParams = {}, data } = config
  if (data) {
    return axios[method](path, data)
  }
  return axios[method](path, {
    params: { t: new Date().getTime() }
    // params: buildQueryParams(queryParams),
  })
}

export default {

  /**
   * @param {QueryParams} queryParams
   */
  async headCollection(path, queryParams = {}) {
    const response = await request('head', path, queryParams)
    return response.headers['X-Total']
  },

  /**
   * @returns {string}
   */
  async headerDocument(path, id) {
    const response = await request('head', idPath(path, id))
    return response.headers['E-Tag']
  },


  /**
   * @param {QueryParams} queryParams
   * @returns {Collection}
   */
  async getCollection(path, queryParams = {}) {
    const response = await request('get', path, { queryParams })
    return response.data
  },


  /**
   * @param {QueryParams} queryParams
   * @returns {Collection}
   */
  async getAll(path, queryParams) {
    return this.getCollection(path, { ...queryParams, all: true })
  },

  /**
   * @param {array} withRels
   * @returns {Document}
   */
  async getDocument(path, id, withRels = undefined) {
    const response = await request('get', idPath(path, id), { queryParams: { withRels } })
    return response.data
  },

  /**
   * @return {Document}
   */
  async create(path, data) {
    const response = await request('post', path, { data })
    return response.data
  },

  /**
   * @param {array} dataArray
   * @returns {Collection}
   */
  async batchCreate(path, dataArray) {
    const response = await request('post', path, { data: dataArray })
    return response.data
  },

  /**
   * @returns {Document}
   */
  async update(path, id, data) {
    const response = await request('patch', idPath(path, id), { data })
    return response.data
  },

  /**
   * @param {QueryParams} queryParams
   * @returns {Collection}
   */
  async batchUpdate(path, data) {
    console.log(data)
    const response = await request('patch', path, { data })
    return response.data
  },

  /**
   * @returns {Document}
   */
  async replace(path, id, data) {
    const response = await request('put', idPath(path, id), { data })
    return response.data
  },

  /**
   * @param {QueryParams} queryParams
   * @returns {Collection}
   */
  async batchReplace(path, queryParams, data) {
    const response = await request('put', path, { queryParams, data })
    return response.data
  },

  /**
   * @returns {void}
   */
  async remove(path, id) {
    await request('delete', idPath(path, id))
    return null
  },

  async batchRemove(path, ids) {
    await request('delete', path, {
      queryParams: {
        query: { 'id': JSON.stringify(ids) }
      }
    })
    return null
  }

}
